Lecture 5
(February 13, 2003)
HANDS-ON WITH VESP- SUM EXAMPLE |
High Level Representation int x,y[6],i; y[0] = 15; y[1] = 23; y[2] = -14; y[3] = 7; y[4] = 126; y[5] = 89; x = y[0]; for(i=1;i< 6;i++) { x = x + y[i];}
|
|
|
|
2007 //Address: 2C Load mov instruction 3001 //Address: 2D 2009 //Address: 2E Load jmp instruction 4056 //Address: 2F 2020 //Address: 30 Load numbers 000F //Address: 31 2021 //Address: 32 0017 //Address: 33 2022 //Address: 34 00F9 //Address: 35 2023 //Address: 36 0007 //Address: 37 2024 //Address: 38 007D //Address: 39 2025 //Address: 3A 0059 //Address: 3B End load numbers 2002 //Address: 3C Initialize loop-count to 6 0006 //Address: 3D 2008 //Address: 3E Initialize index to 20 0020 //Address: 3F 3000 //Address: 40 Move operand to Register-A 0020 //Address: 41 300A //Address: 42 Save sum 0000 //Address: 43 3000 //Address: 44 Move loop count 0002 //Address: 45 2001 //Address: 46 Load -1 into Register-B FFFF //Address: 47 0000 //Address: 48 Add 3002 //Address: 49 Save loop counter 0000 //Address: 4A 5058 //Address: 4B Jump to Halt if loop-count = 0 3000 //Address: 4C Move index to Register-A 0008 //Address: 4D 2001 //Address: 4E Load 1 into Register-B 0001 //Address: 4F 0000 //Address: 50 Increment index by 1 3008 //Address: 51 Save index 0000 //Address: 52 3000 //Address: 53 Move sum into Register-A 000A //Address: 54 4007 //Address: 55 Jump to location 7 0000 //Address: 56 Add 4042 //Address: 57 Jump back to save sum 7000 //Address: 58 Halt |
/*****************************************************************************/ /* VESP COMPUTER * /* Author: A. Yavuz Oruc * /* Copyright © 2000. Sabatech Corporation. All rights reserved. * /*Copying and compiling this program for personal use is permitted. However, * /*no part of this program may be reproduced or distributed in any form or * /*by any means, or stored in a database or retrieval system, without the * /*prior written permission of Sabatech Corporation. (www.sabatech.com) * /*****************************************************************************/ /* This computer program simulates the fetch,decode /* and execute cycles of a hypothetical 16-bit computer, /* called VESP (_V_Ery _Simple _Processor) /* Revised to reduce the address field to 12 bits. 2/13/03 /* VESP has the following registers: /* A: 16 bits (Implicit) It refers to location 0 in VESP'smemory /* B: 16 bits (Implicit) It refers to location 1 in VESP'smemory /* MAR: 13 bits IR: 16 bits PC: 13 bits /* Its instruction repertoire consists of the following instructions: /* ADD: Add Opcode: 000 ----- A = A+B HexCode: 0 /* CMP: Compl Opcode: 001 ----- A = ~A HexCode: 1 /* LDA: Load Opcode: 010 ----- M[IR[3:15] ] = M[MAR+1] HexCode: 2 /* MOV: Move Opcode: 011 ----- M[IR[3:15] ] = M[M[MAR+1][3:15]] HexCode: 3 /* JMP Jump Opcode: 100 ----- PC = IR[3:15] HexCode: 4 /* JEZ: Jump if 0 Opcode: 101 ----- If (A = 0) PC = IR[3:15] HexCode: 5 /* JPS: Jump if + Opcode: 110 ----- If (A > 0) PC = IR[3:15] HexCode: 6 /* HLT: Hlt Opcode: 111 ----- reset = 1 HexCode: 7 /* Programs are entered and displayed in hex code. /* Please communicate all your questions and comments to /* A. Yavuz Oruc, Professor /* University of Maryland, College Park, MD 20742 /* E-mail: yavuz@eng.umd.edu or yavuz@sabatech.com /* June 2000 */ #include <iostream.h> #include <stdio.h> #include <limits.h>
void initialize(void); int readprogram(void); void displayprogram(int progend); void displayregisters(void); void displaymemory(void); void maincycle(void); void fetch(void); void decode(void); void execute(void);
//AYO: Define the registers of the architecture. typedef struct {short MAR,PC,IR,clock; short MEMORY[8192],S,C,F,Z,reset,add,complement; } architecture; architecture vesp;
int j=1;
int main(void) {int address = 0,i = 0,action = 0, step = 0,progend; initialize();//AYO: Initialize all the registers. do {vesp.reset = 0; //AYO: vesp will continue to run unless it is reset. //AYO: Input program, diplay registers or memory cout << "Type \n 0 to enter a program\n " << "1 to display registers\n 2 to display memory: "; cin >> action; cout << "\n"; //AYO: Read the program, display it, and execute it. if(action == 0) {progend = readprogram(); displayprogram(progend); //AYO: Step through or execute the program. while(vesp.reset == 0) {while(step == 0 && vesp.reset == 0) {cout << "Enter 1 if you wish to step the program, and 0 to execute it : "; scanf("%d",&step); if(step == 1) {maincycle(); step = 0; break;} while(vesp.reset == 0) {maincycle();} } }
//AYO: Display the number of instructions and clock cycles executed. cout << "The number of instructions executed = "; printf("%0d",j-1); cout << "\n"; cout << "The number of clock cycles used = "; printf("%0d",vesp.clock); cout << "\n\n"; j = 1; } if (action == 1) displayregisters(); if (action == 2) displaymemory(); if (action == 3) readprogram(); } while (1); }
void initialize(void) {vesp.PC = vesp.MEMORY[0] = vesp.MEMORY[1] = vesp.IR = 0; vesp.reset = 0; vesp.clock = 0; }
int readprogram(void) {int address,instruction,progend,action; char filename[16]; FILE *file; do{ cout << "Enter your program's starting " << "address ( >= 2) as a 3-digit hex number: "; cin >> hex >> vesp.PC; } while (vesp.PC < 2);
address = vesp.PC; cout << "Enter 0 to type in your program or 1 to read it from a file: "; cin >> action; if(action != 0) {cout << "Enter the file name: "; cin >> filename; if( (file = fopen(filename,"r")) != NULL) { while (fscanf(file,"%x",&instruction) != EOF && address < 8192 ) { vesp.MEMORY[address] = instruction; address = address + 1;} } fclose(file); } else do {cout << "Enter instruction " << address -vesp.PC << " using a 4-digit hex number" << "\n"; cout << "Or type -1 to end your program: "; cin >> hex >> instruction; //AYO: read it in hex. vesp.MEMORY[address] = instruction; address = address + 1; } while ( ( vesp.MEMORY[address-1] != -1 ) && (address < 8192)); //AYO: -1 marks the end. if (address >= 8192) {cout << "Memory overflow," << "Please quit from the file menu and restart me!"; return address-1;} progend = address - 1; return progend; }
void displayprogram(int progend) {int i; cout << "\nHere is your program: \n\n"; for (i = vesp.PC; i<= progend; i++) { cout << "Location " << hex << i << ": "; //AYO: display it in hex. printf("%04X",0x0000FFFF & vesp.MEMORY[i]); cout << "\n"; } } void displayregisters(void) {cout << "A = "; printf("%04X", 0x0000FFFF & vesp.MEMORY[0]); cout << ", "; cout << "B = "; printf("%04X", 0x0000FFFF & vesp.MEMORY[1]); cout << ", "; cout << "Z = " << vesp.Z; cout << ", "; cout << "S = " << vesp.S; cout << ", "; cout << "C = " << vesp.C; cout << ", "; cout << "F = " << vesp.F; cout << "\n"; cout << "MAR = "; printf("%03X",vesp.MAR); cout << ", "; cout << "PC = "; printf("%03X",vesp.PC); cout << ", "; cout << "IR = "; printf("%04X",vesp.IR); cout << ", "; cout << "reset = " << vesp.reset << "\n\n"; }
void displaymemory(void) {int location1,location2,i, quotient; char d0,d1,d2,d3; cout << "Enter the first address: "; scanf("%3X",&location1); cout << "Enter the last address: "; scanf("%3X",&location2); cout << "\n"; for (i = location1; i <= location2; i++) {cout << "Location " << i << " : "; // printf("%4X",(short)vesp.MEMORY[i]); cout << "\n"; // number = d0 + 16x(d1 + 16x(d2 + 16xd3)) d0 = vesp.MEMORY[i] % 16; quotient = vesp.MEMORY[i]/16; d1 = quotient % 16; quotient = quotient/16; d2 = quotient % 16; quotient = quotient/16; d3 = quotient % 16; cout << hex << (0x0000FFFF & vesp.MEMORY[i]); cout << "\n"; //cout << hex << d3; //cout << hex << d2; //cout << hex << d1; //cout << hex << d0;
} cout << "\n"; }
void maincycle(void) { cout << "Machine Cycle " << j << ": "; j = j+1; //AYO: Fetch Step cout << "PC = "; printf("%03X",vesp.PC); cout << ", "; cout << "\nFETCH SUBCYCLE\n"; fetch(); cout << "\nClock cycle = "; printf("%0d",vesp.clock); cout << "\n\n"; //AYO: Decode Step cout << "DECODE SUBCYCLE\n"; decode(); cout << "Clock cycle = "; printf("%0d",vesp.clock); cout << "\n\n"; //AYO: Execute Step cout << "EXECUTE SUBCYCLE\n"; vesp.add = vesp.complement = 0; execute(); cout << "Clock cycle = "; printf("%0d",vesp.clock); cout << "\n\n"; //AYO: Display the registers cout << "A = "; printf("%04X",0x0000FFFF & vesp.MEMORY[0]); cout << ", "; cout << "B = "; printf("%04X",0x0000FFFF & vesp.MEMORY[1]); cout << ", "; cout << "Z = " << vesp.Z << ", "; cout << "S = " << vesp.S << ", "; cout << "C = " << vesp.C << ", "; cout << "F = " << vesp.F << "\n"; cout << "MAR = "; printf("%03X",vesp.MAR); cout << ", "; cout << "reset = " << vesp.reset << "\n"; cout << "add = " << vesp.add << "\n"; cout << "complement = " << vesp.complement << "\n\n"; if( (vesp.IR >> 12 ) == 2 || (vesp.IR >> 12 ) == 3) {cout << "Memory["; cout << hex << (vesp.IR & 0x0FFF) << "] = "; printf("%04X",0x0000FFFF & vesp.MEMORY[vesp.IR & 0x0FFF]); cout << ",\n\n";} }
void fetch(void) { //clock cycle 1. Load next instruction's address into MAR. vesp.MAR = vesp.PC; vesp.clock = vesp.clock +1; vesp.PC = vesp.PC +1; //Increment PC. //clock cycle 2. Fetch the next Instruction into IR cout << "MAR = "; printf("%04X",vesp.MAR); cout << ", "; vesp.IR = vesp.MEMORY[vesp.MAR]; vesp.clock = vesp.clock +1; cout << "IR = "; printf("%04X",vesp.IR); cout << ", "; }
void decode(void) {cout << "The decoded instruction is: "; switch( vesp.IR >> 12) {//Add //Complement case 0: cout << "ADD\n"; break; case 1: cout << "CMP\n"; break; //Load //Move case 2: cout << "LDA\n"; break; case 3: cout << "MOV\n"; break; //Jump //Jump if A = 0 case 4: cout << "JMP\n"; break; case 5: cout << "JEZ\n"; break; //Jump if A > 0 //Halt case 6: cout << "JPS\n"; break; case 7: cout << "HLT\n"; break; } }
void execute(void) { short temp; switch(vesp.IR >> 12) {//clock cycle 3. //Add case 0: temp = vesp.MEMORY[0] + vesp.MEMORY[1]; vesp.clock = vesp.clock +1; if(vesp.MEMORY[0] > 0 && vesp.MEMORY[1] > 0 && temp < 0 || vesp.MEMORY[0] < 0 && vesp.MEMORY[1] < 0 && temp >= 0) vesp.F = 1; else vesp.F = 0; //AYO: Set Overflow Flag if (vesp.MEMORY[0] < 0 && vesp.MEMORY[1] < 0 || temp > 0 && (vesp.MEMORY[0] < 0 && vesp.MEMORY[1] > 0 || vesp.MEMORY[0] > 0 && vesp.MEMORY[1] < 0)) vesp.C = 1; else vesp.C = 0; //AYO: Set Carry Flag vesp.MEMORY[0] = temp; //Save the sum in MEMORY[0] //AYO: Set Zero Flag if(vesp.MEMORY[0] == 0) vesp.Z = 1; else vesp.Z = 0; //AYO: Set Sign Flag vesp.S = (vesp.MEMORY[0] & 0x8000 ) >> 15; vesp.add = 1; break; //Complement case 1: vesp.MEMORY[0] = ~vesp.MEMORY[0]; vesp.clock = vesp.clock +1; if(vesp.MEMORY[0] == 0) vesp.Z = 1; else vesp.Z = 0; vesp.S = (vesp.MEMORY[0] & 0x8000 ) >> 15; vesp.complement = 1; break; //Load case 2: vesp.MEMORY[vesp.IR&0x0FFF] = vesp.MEMORY[(vesp.MAR) + 1]; vesp.clock = vesp.clock +1; vesp.PC = vesp.PC + 1; break; //Move case 3: vesp.MEMORY[vesp.IR&0x0FFF] = vesp.MEMORY[vesp.MEMORY[(vesp.MAR) + 1]]; vesp.clock = vesp.clock + 2; vesp.PC = vesp.PC + 1; break; //Jump case 4: vesp.PC = vesp.IR & 0x1FFF;vesp.clock = vesp.clock +1; break; //Branch if A is 0 case 5: if (vesp.MEMORY[0] == 0) {vesp.PC = vesp.IR & 0x0FFF;} vesp.clock = vesp.clock +1; break; //Branch if A is > 0 case 6: if (vesp.MEMORY[0] > 0) {vesp.PC = vesp.IR & 0x0FFF;} vesp.clock = vesp.clock +1; break; //Halt case 7: vesp.reset = 1; vesp.clock = vesp.clock +1; break; } }
|